﻿using ChoMy.Areas.Admin.Models;
using ChoMy.Constants;
using ChoMy.Helpers;
using ChoMy.Models;
using ChoMy.Models.Data;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using PagedList;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Web;
using System.Web.Mvc;

namespace ChoMy.Areas.Admin.Controllers
{
    [Authorize]
    public class RoleController : Controller
    {
        private ChoMyDbContext db = new ChoMyDbContext();

        public ActionResult Index(string search, string sortOrder, int? page, int? pageSize)
        {
            if(User.Identity.Name != "ddduy0106@gmail.com")
            {
                return RedirectToAction("Unauthorized", "Error", new { action = "Index", controller = "Role" });
            }

            var sortList = new List<string> { "Name", "NameVn", "DisplayName" };
            var pageSizeList = new List<int> { 10, 25, 50, 100 };
            int pageNumber = page ?? 1;

            pageSize = pageSize ?? 10;
            sortOrder = sortOrder ?? "Name";

            ViewBag.PageSize = pageSize;
            ViewBag.PageSizeDDL = new SelectList(pageSizeList, pageSize);

            IQueryable<Role> query = db.Roles;

            if (!String.IsNullOrWhiteSpace(search))
            {
                page = 1;

                query = Search(query, search.Trim());
            }

            query = Sort(query, sortOrder, sortList);

            return View(query.ToPagedList(pageNumber, (int)pageSize));
        }

        public ActionResult Details(int? id, string returnListUrl)
        {
            if (id == null)
            {
                return RedirectToAction("BadRequest", "Error");
            }

            Role om = db.Roles
                .FirstOrDefault(x => x.Id == id);

            if (om == null)
            {
                return RedirectToAction("NotFound", "Error");
            }

            ViewBag.ReturnListUrl = returnListUrl;

            return View(om);
        }

        public ActionResult Create(string returnListUrl)
        {
            ViewBag.ReturnListUrl = returnListUrl;

            return View();
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(CreateRoleViewModel model, string returnListUrl)
        {
            if (ModelState.IsValid)
            {
                var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));

                var om = new Role();
                om.Name = model.Name.Trim();

                if(!String.IsNullOrWhiteSpace(model.NameVn))
                {
                    om.NameVn = model.NameVn.Trim();
                }              

                if (!roleManager.RoleExists(om.Name))
                {
                    var role = new IdentityRole();
                    role.Name = om.Name;
                    roleManager.Create(role);

                    db.Roles.Add(om);
                    db.SaveChanges();
                }               

                AlertHandling("create-success", om.Name);

                if (!String.IsNullOrWhiteSpace(returnListUrl))
                {
                    return Redirect(returnListUrl);
                }

                return RedirectToAction("Index");
            }

            ViewBag.ReturnListUrl = returnListUrl;

            return View(model);
        }

        public ActionResult Edit(int? id, string returnListUrl)
        {
            if (id == null)
            {
                return RedirectToAction("BadRequest", "Error");
            }

            Role om = db.Roles
                .FirstOrDefault(x => x.Id == id);

            if (om == null)
            {
                return RedirectToAction("NotFound", "Error");
            }

            var model = new EditRoleViewModel();
            model.Id = om.Id;
            model.Name = om.Name;
            model.NameVn = om.NameVn;

            ViewBag.ReturnListUrl = returnListUrl;

            return View(model);
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit(EditRoleViewModel model, string returnListUrl)
        {
            if (ModelState.IsValid)
            {
                var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));

                Role om = db.Roles.Find(model.Id);
                IdentityRole role = roleManager.FindByName(om.Name);

                om.Name = model.Name.Trim();

                if (!String.IsNullOrWhiteSpace(model.NameVn))
                {
                    om.NameVn = model.NameVn.Trim();
                }  

                role.Name = om.Name;
                roleManager.Update(role);

                db.Entry(om).State = EntityState.Modified;
                db.SaveChanges();

                AlertHandling("edit-success", om.Name);

                if (!String.IsNullOrWhiteSpace(returnListUrl))
                {
                    return Redirect(returnListUrl);
                }

                return RedirectToAction("Index");
            }

            ViewBag.ReturnListUrl = returnListUrl;

            return View(model);
        }

        public ActionResult Delete(int? id, string returnListUrl)
        {
            if (id == null)
            {
                return RedirectToAction("BadRequest", "Error");
            }

            Role om = db.Roles
                .FirstOrDefault(x => x.Id == id);

            if (om == null)
            {
                return RedirectToAction("NotFound", "Error");
            }

            ViewBag.ReturnListUrl = returnListUrl;

            return View(om);
        }

        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id, string returnListUrl)
        {
            var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));

            Role om = db.Roles.Find(id);
            IdentityRole role = roleManager.FindByName(om.Name);
            string tmp = om.Name;

            roleManager.Delete(role);

            db.Roles.Remove(om);
            db.SaveChanges();

            AlertHandling("delete-success", tmp);

            if (!String.IsNullOrWhiteSpace(returnListUrl))
            {
                return Redirect(returnListUrl);
            }

            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult CheckName(string name, int? id)
        {
            string tmp = name.Trim().ToLower();

            Role om = db.Roles
                .FirstOrDefault(x => x.Name.ToLower() == tmp && x.Id != id);

            if (om != null)
            {
                string url = Url.Action("Details", new { id = om.Id });
                string result = String.Format("Tên phân quyền này đã tồn tại. <a href='{0}' target='_blank'>Chi tiết</a>", url);

                return Json(result, JsonRequestBehavior.AllowGet);
            }

            return Json(true, JsonRequestBehavior.AllowGet);
        }

        #region Helpers
        private void AlertHandling(string crud, string name)
        {
            string userName = User.Identity.Name;
            string alertMessage = "";
            string alertType = "alert-success";

            switch (crud)
            {
                case "create-success":
                    alertMessage = String.Format("Bạn vừa tạo mới phân quyền: <b>{0}</b>", name);
                    break;
                case "edit-success":
                    alertMessage = String.Format("Bạn vừa chỉnh sửa phân quyền: <b>{0}</b>", name);
                    break;
                case "delete-success":
                    alertMessage = String.Format("Bạn vừa xóa phân quyền: <b>{0}</b>", name);
                    break;
            }

            if (!String.IsNullOrWhiteSpace(alertMessage))
            {
                Session["alert-message-" + userName] = alertMessage;
                Session["alert-type-" + userName] = alertType;
            }
        }

        private IQueryable<Role> Search(IQueryable<Role> query, string search)
        {
            ViewBag.Search = search;

            search = search.Trim().ToLower();

            query = query.Where(x => x.Name.ToLower().Contains(search) || x.NameVn.ToLower().Contains(search));

            return query;
        }

        private IQueryable<Role> Sort(IQueryable<Role> query, string sortOrder, List<string> sortList)
        {
            ViewBag.SortOrder = sortOrder;

            foreach (string sort in sortList)
            {
                ViewData[sort + "Sort"] = sortOrder == sort + "_desc" ? sort : sort + "_desc";
            }

            if (sortOrder.Contains("_desc"))
            {
                sortOrder = sortOrder.Replace("_desc", "");
                query = query.OrderBy(sortOrder + " descending");
                ViewData[sortOrder + "Icon"] = DataTableConstant.DescSortIcon;
            }
            else
            {
                query = query.OrderBy(sortOrder);
                ViewData[sortOrder + "Icon"] = DataTableConstant.AscSortIcon;
            }

            return query;
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
        #endregion
    }
}